package com.lili.collection.core;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.lili.collection.core.config.InputConfig;
import com.lili.collection.core.config.OutputConfig;
import com.lili.collection.core.config.ProcessConfig;
import com.lili.collection.core.context.Context;
import com.lili.collection.core.context.impl.GenericContext;
import com.lili.collection.core.error.IllegalConfigException;

/**
 * 采集构造器
 *
 * @author lili
 * @date 2023/2/13 20:18
 */
public class DCBuilder {

    private Context context = new GenericContext();

    private DCBuilder() {
    }

    /**
     * 实例化
     */
    public static DCBuilder newInstance() {
        return new DCBuilder();
    }

    /**
     * 设置数据输入配置
     *
     * @return 数据输入配置构造器
     */
    public DCInputBuilder setInputConfig(InputConfig config) {
        if (config == null) throw new IllegalConfigException(StrUtil.format("输入配置未设置"));
        context.setInputConfig(config);
        return new DCInputBuilder(context);
    }

    public class DCInputBuilder {

        private Context context;

        public DCInputBuilder(Context context) {
            this.context = context;
        }

        /**
         * 设置数据加工配置
         *
         * @return 数据输入配置构造器
         */
        public DCInputBuilder setProcessConfig(ProcessConfig config) {
            if (config == null) throw new IllegalConfigException(StrUtil.format("加工配置不能为空"));
            this.context.getProcessConfigList().add(config);
            return this;
        }

        /**
         * 设置数据输出配置
         *
         * @return 数据输出配置构造器
         */
        public DCOutputBuilder setOutputConfig(OutputConfig config) {
            if (config == null) throw new IllegalConfigException(StrUtil.format("输出配置未设置"));
            this.context.setOutputConfig(config);
            return new DCOutputBuilder(this.context);
        }
    }

    public class DCOutputBuilder {

        private Context context;

        public DCOutputBuilder(Context context) {
            this.context = context;
        }

        /**
         * 构建数据流对象
         *
         * @return 数据流对象
         */
        public ExecutorAdapter build() {
            this.validate();
            return new ExecutorAdapter(this.context);
        }

        private void validate() {
            if (this.context.getInputConfig() == null) throw new IllegalConfigException("输入配置未设置");
            if (this.context.getInputConfig().getPlugin() == null) throw new IllegalConfigException("输入插件未设置");
            if (CollUtil.isNotEmpty(this.context.getProcessConfigList())) {
                for (ProcessConfig processConfig : this.context.getProcessConfigList()) {
                    if (processConfig == null) throw new IllegalConfigException("加工配置不能为空");
                    if (processConfig.getPlugin() == null) throw new IllegalConfigException("加工插件未设置");
                }
            }
            if (this.context.getOutputConfig() == null) throw new IllegalConfigException("输出配置未设置");
            if (this.context.getOutputConfig().getPlugin() == null) throw new IllegalConfigException("输出插件未设置");
        }
    }
}
